//////////////////////////////////////////////////
// glParticleManager.cpp
//
// Author: Tarik Belabbas et Adrien Hoffer
//////////////////////////////////////////////////

#include <sys/time.h>
#include "glParticleManager.h"

using namespace std;

ST_SINGLETON_INIT( glParticleManager );

//------------------------------------------------------------------------------
glParticleManager::glParticleManager()
{
	m_emitterId = 1;
	m_previousTime = 0;
}

//------------------------------------------------------------------------------
glParticleManager::~glParticleManager()
{
	map< unsigned int, glParticleEmitter* >::iterator it = m_emitters.begin();

	while ( it != m_emitters.end() )
	{
		delete it->second;

		++it;
	}

	m_emitters.clear();
}

//------------------------------------------------------------------------------
unsigned int glParticleManager::addEmitter()
{
	m_emitters[ m_emitterId ] = new glParticleEmitter();

	return m_emitterId++;
}

//------------------------------------------------------------------------------
void glParticleManager::initialize( unsigned int _emitterId )
{
	glParticleEmitter* emitter = getEmitter( _emitterId );

	if ( !emitter->isInitialized() )
	{
		emitter->initialize();
	}
	/*map< unsigned int, glParticleEmitter* >::iterator it = m_emitters.begin();

	while ( it != m_emitters.end() )
	{
		it->second->initialize();

		++it;
	}*/
}

//------------------------------------------------------------------------------
void glParticleManager::render()
{
	struct timeval timeVal;
	gettimeofday( &timeVal, NULL );
	unsigned int currentTime = timeVal.tv_sec * 1000000 + timeVal.tv_usec;
	unsigned int deltaTime = currentTime - m_previousTime;
	m_previousTime = currentTime;

	map< unsigned int, glParticleEmitter* >::iterator it = m_emitters.begin();

	while ( it != m_emitters.end() )
	{
		if ( it->second->isInitialized() )
		{
			it->second->render( deltaTime, currentTime );
		}

		++it;
	}
}

//------------------------------------------------------------------------------
glParticleEmitter* glParticleManager::getEmitter( unsigned int _emitterId )
{
	glParticleEmitter* emitter = m_emitters[ _emitterId ];

	ST_ASSERT( ( emitter != NULL ), ( "Invalid _emitterId parameter, %d", _emitterId ) );

	return emitter;
}

//------------------------------------------------------------------------------
void glParticleManager::addTexture( unsigned int _emitterId,
		const char* _texturePath )
{
	glParticleEmitter* emitter = getEmitter( _emitterId );

	emitter->addTexture( _texturePath );
}

//------------------------------------------------------------------------------
void glParticleManager::setPosition( unsigned int _emitterId,
		const glm::vec3& _position )
{
	glParticleEmitter* emitter = getEmitter( _emitterId );

	emitter->setPosition( _position );
}

//------------------------------------------------------------------------------
void glParticleManager::setDirection( unsigned int _emitterId,
		const glm::vec3& _direction )
{
	glParticleEmitter* emitter = getEmitter( _emitterId );

	emitter->setDirection( _direction );
}

//------------------------------------------------------------------------------
void glParticleManager::setNbParticles( unsigned int _emitterId,
		unsigned int _nbParticles )
{
	glParticleEmitter* emitter = getEmitter( _emitterId );

	emitter->setNbParticles( _nbParticles );
}

//------------------------------------------------------------------------------
void glParticleManager::setAdvectVS( unsigned int _emitterId,
		const char* _advectVS )
{
	glParticleEmitter* emitter = getEmitter( _emitterId );

	emitter->setAdvectVS( _advectVS );
}

//------------------------------------------------------------------------------
void glParticleManager::setRenderVS( unsigned int _emitterId,
		const char* _renderVS )
{
	glParticleEmitter* emitter = getEmitter( _emitterId );

	emitter->setRenderVS( _renderVS );
}

//------------------------------------------------------------------------------
void glParticleManager::setRenderFS( unsigned int _emitterId,
		const char* _renderFS )
{
	glParticleEmitter* emitter = getEmitter( _emitterId );

	emitter->setRenderFS( _renderFS );
}

